// 文件路径: dbms/AdvancedQueryTest.java
package com.dbms;

import com.dbms.common.Column;
import com.dbms.common.QueryResult;
import com.dbms.common.Tuple;
import java.io.File;

/**
 * 【已更新】
 * 高级 SQL 功能的综合测试类。
 *
 * 测试目标：
 *  1. VARCHAR(n) 长度约束
 *  2. ORDER BY 排序
 *  3. LIMIT 分页
 *  4. GROUP BY 分组与聚合
 *  5. HAVING 聚合条件过滤
 *  6. 综合测试（多功能联合使用）
 *  7. 注释功能（支持 SQL 单行、多行注释）
 *
 * 测试方式：
 *  - 通过 DbmsCore.processSql(sql) 执行 SQL
 *  - 调用 printResult() 方法输出结果
 */
public class AdvancedQueryTest {

    // 数据库和日志文件名称，保证测试使用独立文件，互不干扰
    private static final String DB_FILE_NAME = "advanced_query_test.db";
    private static final String LOG_FILE_NAME = "advanced_query_test.log";

    /**
     * 测试入口方法。
     * 包含所有测试步骤：环境准备、表创建、数据插入、各功能测试及输出。
     */
    public static void main(String[] args) {
        System.out.println("============== 高级SQL功能集成测试开始 ==============");

        // 1. 测试前环境清理
        System.out.println("\n--- 1. 准备阶段：清理环境 ---");
        new File(DB_FILE_NAME).delete();  // 删除旧数据库文件
        new File(LOG_FILE_NAME).delete(); // 删除旧日志文件
        // 【核心修正】DbmsCore 使用带有文件名的构造函数，保证测试环境独立
        DbmsCore dbms = new DbmsCore(DB_FILE_NAME, LOG_FILE_NAME);
        System.out.println("测试环境初始化完毕。");

        // 2. 测试 VARCHAR(n) 约束
        System.out.println("\n--- 2. 测试 VARCHAR(n) 约束 ---");
        System.out.println("--> CREATE TABLE employees (id INT PRIMARY KEY, name VARCHAR(20), dept VARCHAR(30), salary INT);");
        printResult(dbms.processSql("CREATE TABLE employees (id INT PRIMARY KEY, name VARCHAR(20), dept VARCHAR(30), salary INT);"));
        System.out.println("\n--> (预期成功) INSERT INTO employees VALUES (1, 'short_name', 'Tech', 5000);");
        printResult(dbms.processSql("INSERT INTO employees VALUES (1, 'short_name', 'Tech', 5000);"));
        System.out.println("\n--> (预期失败) INSERT INTO employees VALUES (2, 'a_very_very_long_name_that_exceeds_limit', 'Tech', 6000);");
        printResult(dbms.processSql("INSERT INTO employees VALUES (2, 'a_very_very_long_name_that_exceeds_limit', 'Tech', 6000);"));
        System.out.println("✅ VARCHAR(n) 长度约束测试完毕。\n");

        // 3. 插入测试数据
        System.out.println("--- 3. 准备测试数据 ---");
        dbms.processSql("INSERT INTO employees VALUES (10, 'Carol', 'Sales', 7200);");
        dbms.processSql("INSERT INTO employees VALUES (2, 'Alice', 'Tech', 8000);");
        dbms.processSql("INSERT INTO employees VALUES (5, 'Frank', 'HR', 5500);");
        dbms.processSql("INSERT INTO employees VALUES (3, 'David', 'Sales', 7000);");
        dbms.processSql("INSERT INTO employees VALUES (8, 'Bob', 'Tech', 9500);");
        dbms.processSql("INSERT INTO employees VALUES (6, 'Grace', 'Tech', 12000);");
        dbms.processSql("INSERT INTO employees VALUES (4, 'Eve', 'HR', 6000);");
        System.out.println("测试数据已插入。当前全表数据如下：");
        printResult(dbms.processSql("SELECT * FROM employees;"));

        // 4. 测试 ORDER BY
        System.out.println("\n--- 4. 测试 ORDER BY ---");
        System.out.println("--> (预期：按薪水升序) SELECT * FROM employees ORDER BY salary ASC;");
        printResult(dbms.processSql("SELECT * FROM employees ORDER BY salary ASC;"));
        System.out.println("--> (预期：按姓名降序) SELECT * FROM employees ORDER BY name DESC;");
        printResult(dbms.processSql("SELECT * FROM employees ORDER BY name DESC;"));
        System.out.println("✅ ORDER BY 测试完毕。\n");

        // 5. 测试 LIMIT
        System.out.println("\n--- 5. 测试 LIMIT ---");
        System.out.println("--> (预期：返回前3条) SELECT * FROM employees ORDER BY id ASC LIMIT 3;");
        printResult(dbms.processSql("SELECT * FROM employees ORDER BY id ASC LIMIT 3;"));
        System.out.println("--> (预期：跳过2条，返回后3条) SELECT * FROM employees ORDER BY id ASC LIMIT 2, 3;");
        printResult(dbms.processSql("SELECT * FROM employees ORDER BY id ASC LIMIT 2, 3;"));
        System.out.println("✅ LIMIT 测试完毕。\n");

        // 6. 测试 GROUP BY
        System.out.println("\n--- 6. 测试 GROUP BY ---");
        System.out.println("--> (预期：按部门分组并计数) SELECT dept, COUNT(*) FROM employees GROUP BY dept;");
        printResult(dbms.processSql("SELECT dept, COUNT(*) FROM employees GROUP BY dept;"));
        System.out.println("\n--> (预期：语义错误) SELECT name, COUNT(*) FROM employees GROUP BY dept;");
        printResult(dbms.processSql("SELECT name, COUNT(*) FROM employees GROUP BY dept;"));
        System.out.println("✅ GROUP BY 测试完毕。\n");

        // 7. 测试 HAVING
        System.out.println("\n--- 7. 测试 HAVING ---");
        System.out.println("--> (预期：只返回人数大于2的部门) SELECT dept, COUNT(*) FROM employees GROUP BY dept HAVING COUNT(*) > 2;");
        printResult(dbms.processSql("SELECT dept, COUNT(*) FROM employees GROUP BY dept HAVING COUNT(*) > 2;"));
        System.out.println("✅ HAVING 测试完毕。\n");

        // 8. 综合测试：多个功能联合
        System.out.println("\n--- 8. 综合测试 (已修复) ---");
        System.out.println("--> (预期：查询薪水>=7000的，按部门分组，筛选人数>=2的部门，按部门名降序，只取第1个结果)");
        String complexQuery = "SELECT dept, COUNT(*) FROM employees WHERE salary >= 7000 GROUP BY dept HAVING COUNT(*) >= 2 ORDER BY dept DESC LIMIT 1;";
        System.out.println("--> " + complexQuery);
        printResult(dbms.processSql(complexQuery));
        System.out.println("✅ 综合测试完毕。\n");

        // 9. 注释功能测试
        System.out.println("\n--- 9. 测试注释功能 ---");
        System.out.println("--> (预期：与上一个综合测试结果相同) 执行一个带有大量注释的复杂查询");
        String queryWithComments =
                "-- 这是一个完整的查询，用于测试注释功能\n" +
                        "SELECT \n" +
                        "    dept, -- 选择部门列\n" +
                        "    COUNT(*) -- 计算每个部门的员工总数\n" +
                        "FROM \n" +
                        "    employees -- 从员工表\n" +
                        "WHERE \n" +
                        "    salary >= 7000 -- 只考虑高薪员工\n" +
                        "GROUP BY \n" +
                        "    dept -- 按部门进行分组\n" +
                        "HAVING \n" +
                        "    COUNT(*) >= 2 -- 只看那些至少有2名高薪员工的部门\n" +
                        "ORDER BY \n" +
                        "    dept DESC -- 按部门名称降序排列\n" +
                        "LIMIT 1; -- 只取第一个结果";
        System.out.println("--> " + queryWithComments);
        printResult(dbms.processSql(queryWithComments));
        System.out.println("✅ 注释功能测试完毕。\n");

        // 所有测试结束
        System.out.println("============== 所有高级SQL功能测试结束 ==============");
        dbms.shutdown();
    }

    /**
     * 工具方法：打印查询结果。
     *
     * @param result SQL 执行返回的 QueryResult 对象
     *               - 若成功，打印表头和行数据
     *               - 若失败，打印错误信息
     */
    private static void printResult(QueryResult result) {
        if (result == null) return;
        if (result.isSuccess) {
            // 打印列名
            if (result.schema != null && !result.tuples.isEmpty()) {
                for (Column col : result.schema.getColumns()) {
                    System.out.print(col.getColumnName() + "\t | ");
                }
                System.out.println("\n-------------------------------------------");
                // 打印行数据
                for (Tuple tuple : result.tuples) {
                    System.out.println(tuple.toString());
                }
            }
            // 打印额外消息（如：执行成功提示）
            if (result.message != null) {
                System.out.println(result.message);
            }
        } else {
            // 打印错误信息
            System.err.println("ERROR: " + result.message);
        }
        System.out.println();
    }
}
